﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.ServiceModel.DomainServices.Client;
using GSSoftSL.Web.Models;
using GSSoftSL.Web.Services;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using Microsoft.Practices.ServiceLocation;

namespace GSSoftSL.ViewModel.HocVienVM
{
    /// <summary>
    /// This class contains properties that a View can data bind to.
    /// <para>
    /// Use the <strong>mvvminpc</strong> snippet to add bindable properties to this ViewModel.
    /// </para>
    /// <para>
    /// See http://www.galasoft.ch/mvvm/getstarted
    /// </para>
    /// </summary>
    public class HocVienKhoaHocViewModel : ViewModelBase
    {
        private GSSoftContext _dc;
        public GSSoftContext DC
        {
            get { return _dc; }
            set { _dc = value; }
        }

        /// <summary>
        /// Initializes a new instance of the HocVienEditViewModel class.
        /// </summary>
        public HocVienKhoaHocViewModel()//GSSoftContext context, HocVienMainViewModel mainViewModel)
        {
            _dc = ServiceLocator.Current.GetInstance<DomainContext>("HocVien") as GSSoftContext;
            MainViewModel = ServiceLocator.Current.GetInstance<HocVienMainViewModel>("HocVien");
            MainViewModel.IsBusy = true;
            IsBusy = true;
            _dc.Load<Mon>(_dc.GetMonsQuery().OrderBy(n => n.ThuTu), LoadBehavior.RefreshCurrent, LoadMon_Completed, null);
            //_dc.Load<Lop>(_dc.getL.OrderBy(n => n.ThuTu), LoadLop_Completed, null);
            //_dc.Load<Truong>(_dc.GetTruongsQuery(), LoadTruong_Completed, null);
        }

        private void LoadMon_Completed(LoadOperation<Mon> load)
        {
            var lstMons = load.Entities.ToList();
            lstMons.Insert(0, new Mon(){ MaMon = "-1", TenMon = "- Chọn môn -"});
            Mons = lstMons.ToArray();
            IsBusy = false;
        }

        private HocVienMainViewModel _mainViewModel;
        public HocVienMainViewModel MainViewModel
        {
            get { return _mainViewModel; }
            set { _mainViewModel = value; }
        }
        
        //private bool _isBusy = false;
        public bool IsBusy
        {
            get { return MainViewModel.IsBusy; }
            set { MainViewModel.IsBusy = value; }
        }
        
        private HocVien _hocVien;
        public HocVien HocVien
        {
            get
            {
                return _hocVien;
            }
            set
            {
                if (_hocVien == value)
                {
                    return;
                }
                _hocVien = value;
                RaisePropertyChanged("HocVien");
                if (_hocVien == null)
                    KhoaHocsIn = null;
                else
                {
                    IsBusy = true;
                    _dc.Load<KhoaHoc>(_dc.GetKhoaHocsHocVienTheoHocQuery(_hocVien.MaHV), LoadBehavior.RefreshCurrent, LoadKhoaHocHocVien_Completed, null);
                    
                }
                SaveCommand.RaiseCanExecuteChanged();
                //AddLopCommand.RaiseCanExecuteChanged();
            }
        }

        private void LoadKhoaHocHocVien_Completed(LoadOperation<KhoaHoc> load)
        {
            KhoaHocsIn = new ObservableCollection<KhoaHoc>(load.Entities); //load.Entities.ToList();
            IsBusy = false;
        }


        private Mon[] _mons = null;
        public Mon[] Mons
        {
            get
            {
                return _mons;
            }
            set
            {
                if (_mons == value)
                {
                    return;
                }
                _mons = value;
                RaisePropertyChanged("Mons");
                Mon = _mons[0];
            }
        }
        
        private Mon _mon = null;
        public Mon Mon
        {
            get
            {
                return _mon;
            }
            set
            {
                if (_mon == value)
                {
                    return;
                }
                _mon = value;
                RaisePropertyChanged("Mon");
                if (_mon != null && _mon.MaMon != "-1")
                {
                    IsBusy = true;
                    _dc.Load<Lop>(
                        _dc.GetLopsQuery().Where(n => n.MaMon == _mon.MaMon).OrderBy(n => n.MaLop),
                        LoadBehavior.RefreshCurrent,
                        LoadLop_Completed, null);
                }
                else
                {
                    Lops = null;
                    KhoaHocs = null;
                }
            }
        }

        private void LoadLop_Completed(LoadOperation<Lop> load)
        {
            var lstLops = load.Entities.ToList();
            lstLops.Insert(0, new Lop() {MaLop = "-1", TenLop = "- Chọn lớp -"});
            Lops = lstLops.ToArray();
            IsBusy = false;
        }

        private Lop[] _lops = null;
        public Lop[] Lops
        {
            get
            {
                return _lops;
            }
            set
            {
                if (_lops == value)
                {
                    return;
                }
                _lops = value;
                RaisePropertyChanged("Lops");
                if (_lops != null && _lops.Length > 0)
                    Lop = _lops[0];
                else
                    Lop = null;
            }
        }

        
        private Lop _lop = null;
        public Lop Lop
        {
            get
            {
                return _lop;
            }
            set
            {
                if (_lop == value)
                {
                    return;
                }
                _lop = value;
                RaisePropertyChanged("Lop");
                if (_lop != null && _lop.MaLop != "-1")
                {
                    IsBusy = true;
                    _dc.Load<KhoaHoc>(
                        _dc.GetKhoaHocsWithGiaoVienQuery().Where(n => n.LopId == _lop.LopId).OrderByDescending(n => n.STT),
                        LoadBehavior.RefreshCurrent,
                        LoadKhoaHoc_Completed, null);
                }
                else
                {
                    KhoaHocs = null;
                }
                //AddLopCommand.RaiseCanExecuteChanged();
            }
        }

        private void LoadKhoaHoc_Completed(LoadOperation<KhoaHoc> load)
        {
            KhoaHocs = load.Entities.ToArray();
            IsBusy = false;
        }
        
        public const string KhoaHocsPropertyName = "KhoaHocs";
        private KhoaHoc[] _khoaHocs = null;
        public KhoaHoc[] KhoaHocs
        {
            get
            {
                return _khoaHocs;
            }
            set
            {
                if (_khoaHocs == value)
                {
                    return;
                }

                RaisePropertyChanging(KhoaHocsPropertyName);
                _khoaHocs = value;
                RaisePropertyChanged(KhoaHocsPropertyName);
            }
        }
        
        public const string SelectedKhoaHocPropertyName = "SelectedKhoaHoc";
        private KhoaHoc _selectedKhoaHoc = null;
        public KhoaHoc SelectedKhoaHoc
        {
            get
            {
                return _selectedKhoaHoc;
            }
            set
            {
                if (_selectedKhoaHoc == value)
                {
                    return;
                }

                RaisePropertyChanging(SelectedKhoaHocPropertyName);
                _selectedKhoaHoc = value;
                RaisePropertyChanged(SelectedKhoaHocPropertyName);
            }
        }

        private ObservableCollection<KhoaHoc> _khoaHocsIn = null;
        public ObservableCollection<KhoaHoc> KhoaHocsIn
        {
            get
            {
                return _khoaHocsIn;
            }
            set
            {
                if (_khoaHocsIn == value)
                {
                    return;
                }
                _khoaHocsIn = value;
                RaisePropertyChanged("KhoaHocsIn");
            }
        }

        
        private KhoaHoc _selectedKhoaHocIn = null;
        public KhoaHoc SelectedKhoaHocIn
        {
            get
            {
                return _selectedKhoaHocIn;
            }
            set
            {
                if (_selectedKhoaHocIn == value)
                {
                    return;
                }
                _selectedKhoaHocIn = value;
                RaisePropertyChanged("SelectedKhoaHocIn");
            }
        }

        private RelayCommand _addLopCommand;
        public RelayCommand AddLopCommand
        {
            get
            {
                return _addLopCommand
                       ?? (_addLopCommand = new RelayCommand(
                                         () =>
                                             {
                                                 if (HocVien != null && KhoaHocsIn != null && _selectedKhoaHoc != null &&
                                                         KhoaHocsIn.Where(n => n.KhoaHocId == _selectedKhoaHoc.KhoaHocId).Count() == 0)
                                                 {
                                                     _khoaHocsIn.Add(_selectedKhoaHoc);
                                                 }
                                             }));
            }
        }

        private RelayCommand _removeLopCommand;
        public RelayCommand RemoveLopCommand
        {
            get
            {
                return _removeLopCommand
                    ?? (_removeLopCommand = new RelayCommand(
                                          () =>
                                          {
                                              if (_hocVien == null || _khoaHocsIn == null || _selectedKhoaHocIn == null)
                                                  return;
                                              if (KhoaHocsIn.Count(n => n.KhoaHocId == _selectedKhoaHocIn.KhoaHocId) != 1)
                                                  return;
                                              KhoaHocsIn.Remove(KhoaHocsIn.Single(n => n.KhoaHocId == _selectedKhoaHocIn.KhoaHocId));
                                              SelectedKhoaHocIn = null;
                                          }));
            }
        }

        private RelayCommand _saveCommand;
        public RelayCommand SaveCommand
        {
            get
            {
                return _saveCommand
                    ?? (_saveCommand = new RelayCommand(
                                          () =>
                                              {
                                                  if (HocVien == null || _dc.IsSubmitting)
                                                      return;
                                                  ConfirmWindow.CreateNew("Bạn có muốn lưu?", Save);
                                                  
                                              },
                                          () =>
                                              {
                                                  return HocVien != null;
                                              }));
            }
        }

        private void Save()
        {
            Guid[] khoaHocs = _khoaHocsIn.Select(n => n.KhoaHocId).ToArray();
            IsBusy = true;
            _dc.RegisterKhoaHocsHocVien(_hocVien.MaHV, khoaHocs, RegisterKhoaHocsHocVien_Completed, null);
        }

        private void RegisterKhoaHocsHocVien_Completed(InvokeOperation io)
        {
            IsBusy = false;
        }

        private RelayCommand _reloadCommand;
        /// <summary>
        /// Gets the ReloadCommand.
        /// </summary>
        public RelayCommand ReloadCommand
        {
            get
            {
                return _reloadCommand
                    ?? (_reloadCommand = new RelayCommand(
                                          () =>
                                              {
                                                  HocVien hv = HocVien;
                                                  HocVien = null;
                                                  HocVien = hv;
                                              }));
            }
        }

    }
}